package com.face.controller;

import com.face.common.Page;
import com.face.common.Result;
import com.face.common.ResultCode;
import com.face.entity.Account;
import com.face.exception.*;
import com.face.form.ChangePasswordForm;
import com.face.service.AccountService;
import com.face.util.ThreadUtil;
import com.face.wrapper.AccountWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/account")
public class AccountController {

    @Autowired
    private AccountService accountService;

    @PostMapping("/register")
    public Result register(@RequestBody Account account) {
        try {
            accountService.register(account);
        } catch (AccountExistException e) {
            return Result.failure(ResultCode.ACCOUNT_EXIST);
        } catch (EmailExistException e) {
            return Result.failure(ResultCode.EMAIL_EXIST);
        }

        return Result.success();
    }

    /**
     * 检查用户名、邮箱是否可用
     * @param type  类型 username/email
     * @param value
     * @return
     */
    @GetMapping("/check")
    public Result checkUsernameOrEmail(@RequestParam String type, @RequestParam String value) {
        if ("username".equals(type)) {
            Account account = accountService.findByUsername(value);
            if (account != null) {
                return Result.failure(ResultCode.ACCOUNT_EXIST);
            }
        } else if ("email".equals(type)) {
            Account account = accountService.findByEmail(value);
            if (account != null) {
                return Result.failure(ResultCode.EMAIL_EXIST);
            }
        } else {
            return Result.failure(ResultCode.BAD_PARAMETER);
        }
        return Result.success();
    }

    @GetMapping("/sendEmail")
    public Result sendEmail(@RequestParam("email") String email) {
        Account account = accountService.findByEmail(email);
        if (account == null) {
            return Result.failure(ResultCode.NO_ACCOUNT);
        }
        if (account.getStatus() != 1) {
            return Result.failure(ResultCode.ACCOUNT_ACTIVEED);
        }
        ThreadUtil.execute(() -> accountService.sendEmail(account));
        return Result.success();
    }

    @GetMapping("/list")
    public Result list(String shopId, @RequestParam(value = "page", defaultValue = "1") Integer page,
                       @RequestParam(value = "limit", defaultValue = "10") Integer limit,
                       String username, String realname, Integer roleId, @RequestParam(value = "sort", defaultValue = "createTime") String sort,
                       @RequestParam(value = "order", defaultValue = "asc") String order) {
        if (shopId == null) {
            return Result.failure(ResultCode.NOT_ENOUGH_PARAMETER);
        }
        if (StringUtils.isEmpty(shopId)) {
            return Result.failure(ResultCode.BAD_PARAMETER);
        }
        Page<AccountWrapper> pageResult;
        try {
            pageResult = accountService.list(shopId, page, limit, username, realname, roleId, sort + " " + order);
            if (pageResult.getTotal() == 0) {
                return Result.failure(ResultCode.NO_RECORDS);
            }
        } catch (ArgumentException e) {
            return Result.failure(ResultCode.BAD_PARAMETER);
        } catch (ServiceException e) {
            return Result.failure(ResultCode.NO_USER_RECORD);
        }

        Result rs = new Result(ResultCode.QUERY_SUCCESS);
        rs.setData(pageResult);
        return rs;
    }

    @PostMapping("/createAccount")
    public Result createAccount(@RequestBody Account account) {
        try {
            accountService.saveAccount(account);
        } catch (AccountExistException e) {
            return Result.failure(ResultCode.ACCOUNT_EXIST);
        } catch (EmailExistException e) {
            return Result.failure(ResultCode.EMAIL_EXIST);
        }

        return Result.success();
    }

    @PatchMapping("/update")
    public Result updateAccount(@RequestBody Account account) {
        accountService.updateAccount(account);
        return Result.success();
    }

    @PatchMapping("{username}")
    public Result resetPassword(@PathVariable("username") String username) {
        Integer i = accountService.resetPassword(username);
        if (i < 0) {
            return Result.failure(ResultCode.UPDATE_USER_FAIL);
        }
        return Result.success();
    }

    @GetMapping("/{username}")
    public Result findByUsername(@PathVariable("username") String username) {
        Account account = accountService.findByUsername(username);
        return Result.success(account);
    }

    @DeleteMapping("/{username}")
    public Result deleteAccount(@PathVariable("username") String username) {
        if (username == null) {
            return Result.failure(ResultCode.BAD_PARAMETER);
        }
        Integer i = accountService.deleteAccount(username);
        if (i < 0) {
            return Result.failure(ResultCode.UPDATE_USER_FAIL);
        }
        return Result.success();
    }

    @PatchMapping("/password")
    public Result changePassword(@RequestBody ChangePasswordForm form) {
        try {
            accountService.changePassword(form);
        } catch (OldPasswordErrorException e) {
            return Result.failure(ResultCode.OLDPASSWORD_ERROR);
        }
        return Result.success();
    }

    @GetMapping("/listAll")
    public Result listAll(@RequestParam String shopId){
        List<Account> list = accountService.findAllByShopId(shopId);
        return Result.success(list);

    }
}
